﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Stauffware.Common.Core;
using Stauffware.Common.Time;
using System.Globalization;
using NUnit.Framework;

namespace UnitTests.Core.Parsing
{
	//#################################################################################

	public class DecimalTest
	{
		public static TestParams[] Testcases = 
		{
			new TestParams("0", "0", 0.0m, NumberParseOptions.None),
			new TestParams("1", "1", 1m, NumberParseOptions.None),
			new TestParams("-1", "-1", -1m, NumberParseOptions.AllowLeadingSign),

			new TestParams(Decimal.MaxValue.ToString(), Decimal.MaxValue.ToString(), 
							Decimal.MaxValue, NumberParseOptions.None),
			new TestParams(Decimal.MinValue.ToString(), Decimal.MinValue.ToString(), 
							Decimal.MinValue, NumberParseOptions.AllowLeadingSign),

			// NEED LOTS MORE ...


		};

		//-----------------------------------------------------------------------------

		[Test, TestCaseSource("Testcases")]
		public static void TestAll (TestParams prams)
		{
			DecimalParser parser = new DecimalParser(prams.Options);
			DecimalParse parse = parser.Parse(prams.InputText);
			prams.Validate(parse);
		}
	}

	//#################################################################################

	public class TestParams
	{
		// the input text to be parsed
		public string InputText;

		// the options to use during parsing
		public NumberParseOptions Options;

		// the expected Parse.Value
		public decimal? ExpectedValue;

		// the expected error
		public string ExpectedError;

		// the expected Parse.ParsedText
		public string ExpectedParsedText;

		// constructor for positive testcases
		public TestParams (string input, string expParseText, decimal expValue, NumberParseOptions options)
		{
			this.InputText = input;
			this.Options = options;
			this.ExpectedValue = expValue;
			this.ExpectedError = null;
			this.ExpectedParsedText = expParseText;
		}

		// constructor for negative testcases
		public TestParams (string input, string expParseText, NumberParseOptions options, string expError)
		{
			this.InputText = input;
			this.Options = options;
			this.ExpectedValue = null;
			this.ExpectedError = expError;
			this.ExpectedParsedText = expParseText;
		}

		/// <summary>
		/// Performs type-independent validation on the given parse result.
		/// </summary>
		public void Validate (DecimalParse parse)
		{
			NUnit.Framework.Assert.AreEqual(this.ExpectedParsedText, parse.ParsedText, "ParsedText");
			NUnit.Framework.Assert.AreEqual(this.ExpectedValue, parse.Value, "Value");
			NUnit.Framework.Assert.AreEqual(this.ExpectedError, parse.ErrorMessage, "ErrorMessage");
			NUnit.Framework.Assert.AreEqual(this.ExpectedValue != null, parse.GotValue, "GotValue");
			NUnit.Framework.Assert.AreEqual(this.ExpectedError != null, parse.IsError, "IsError");
			NUnit.Framework.Assert.AreEqual((this.ExpectedValue == null) && (this.ExpectedError == null),
																		parse.IsEmpty, "IsEmpty");
		}

		// produce nice display in NUnit GUI
		public override string ToString ()
		{
			if (this._dispStr == null)
			{
				this._dispStr = Chars.LeftDoubleQuote.Unicode + this.InputText + 
								Chars.RightDoubleQuote.Unicode + " " + Chars.RightArrow.Unicode + " ";

				if (this.ExpectedValue != null)
					this._dispStr += this.ExpectedValue.ToString();
				else if (this.ExpectedError != null)
					this._dispStr += "<" + this.ExpectedError + ">";

				this._dispStr += ", " + Chars.LeftDoubleQuote.Unicode + this.ExpectedParsedText + 
								Chars.RightDoubleQuote.Unicode + "; " + this.Options.ToString();
			}
			return this._dispStr;
		}
		private string _dispStr;

	}

	//#################################################################################

	//public class DecimalParsing
	//{

	//    //[TestCase("0", "0", (decimal) 0.0m, NumberParseOptions.None)]
	//    //[TestCase("1", "1", 1m, NumberParseOptions.None)]
	//    //[TestCase("-1", "-1", -1m, NumberParseOptions.AllowLeadingSign)]
	//    //[TestCase("79228162514264337593543950335", "79228162514264337593543950335", 79228162514264337593543950335m, NumberParseOptions.None)]

	//    public static void PosTest (string input, string xParsed, decimal xValue, NumberParseOptions options)
	//    {
	//        DecimalParser parser = new DecimalParser();
	//        DecimalParse parse = parser.Parse(input, options);

	//        NUnit.Framework.Assert.AreEqual(xParsed, parse.ParsedText, "ParsedText");
	//        NUnit.Framework.Assert.AreEqual(xValue, parse.Value, "Value");
	//        NUnit.Framework.Assert.AreEqual(null, parse.ErrorMessage, "ErrorMessage");
	//        NUnit.Framework.Assert.AreEqual(true, parse.GotValue, "GotValue");
	//        NUnit.Framework.Assert.AreEqual(false, parse.IsError, "IsError");
	//        NUnit.Framework.Assert.AreEqual(false, parse.IsEmpty, "IsEmpty");
	//    }

	//    private static void junk ()
	//    {
	//        decimal d = 0m;
	//        d = 0.0m;
	//    }

	//}
}
